home *** CD-ROM | disk | FTP | other *** search
- Subject: v18i104: Rwho with a users(1)-style output
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: pkern <pkern@csri.toronto.edu>
- Posting-number: Volume 18, Issue 104
- Archive-name: ru2
-
- Print a users(1)-style list of names for each host in the rwho spool directory
-
- Before running make, choose the proper CAPLIB (ie. -ltermlib or -ltermcap).
-
- Since rwho is pretty much a BSD animal (I think), the code has only been
- tested on a vax (BSD 4.2), on a Sun 4 and on Sun 3s (SunOS 3.5 & 4.0)
-
- Possible ru options:
- -a print all names regardless of idle time (not unlike "rwho -a").
- -c for repeated names, print the total number of repeats.
- -d like -s but list hosts alphabetically, regardless of their subdomains.
- -m don't drop repeated names.
- -r mimic rwho(1) output.
- -s print lists by host instead of by subdomain.
- -u list uptimes like ruptime(1).
- -w start a fresh line before the output can wrap around.
- -h restrict output to those hosts given on the command line.
- -l restrict output to those systems hosting the given users.
- -D restrict output to those hosts within the given subdomain.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # If this archive is complete, you will see the following message at the end:
- # "End of shell archive."
- # Contents:
- # Readme Makefile ru.l ru.c
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f Readme -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"Readme\"
- else
- echo shar: Extracting \"Readme\" \(2176 characters\)
- sed "s/^X//" >Readme <<'END_OF_Readme'
- XRu:
- X print a users(1)-style list of names for each host in the rwho spool directory
- X
- XBefore running make, choose the proper CAPLIB (ie. -ltermlib or -ltermcap).
- X
- XSince rwho is pretty much a BSD animal (I think), the code has only been
- Xtested on a vax (BSD 4.2), on a Sun 4 and on Sun 3s (SunOS 3.5 & 4.0)
- X
- XPossible ru options:
- X-a print all names regardless of idle time (not unlike "rwho -a").
- X-c for repeated names, print the total number of repeats.
- X-d like -s but list hosts alphabetically, regardless of their subdomains.
- X-m don't drop repeated names.
- X-r mimic rwho(1) output.
- X-s print lists by host instead of by subdomain.
- X-u list uptimes like ruptime(1).
- X-w start a fresh line before the output can wrap around.
- X-h restrict output to those hosts given on the command line.
- X-l restrict output to those systems hosting the given users.
- X-D restrict output to those hosts within the given subdomain.
- X
- XThanks to getopt(3) the options listed above can be mixed and matched at will.
- XFor example:
- X ru -ral joe jack
- X prints rwho-style output (-r) of those systems hosting users
- X joe and/or jack (-l joe jack) regardless of their idle-times (-a).
- X ru -smD ai
- X lists host-by-host (-s) the users (including repeated logins (-m))
- X within the ai subdomain (-D ai).
- X
- XSome options override others (eg. -d overrides -s, -m overrides -c,
- X-u overrides -r). All options are subject to restriction by -h or -l and/or -D.
- X
- XRu only uses existing spooled data so the displayed info could be up to 5 mins
- Xout of date. SUN's rusers(1c) seems to actively poll daemons throughout the
- Xlocal network ... which means it provides up-to-date info but it seems to
- Xtake an awfully long time and also requires the services of another daemon.
- X
- XRu was first written when everything here was still mainly on vaxes
- X(it was also called rusers, then) so I was pleasantly surprised to discover
- XSUN's rusers after CSRI made the final move to Suns. It was kind of interesting
- Xto see how they paralleled each other and how they differed (ie. options, etc.).
- X
- XAnyhow, hope it's useful.
- X
- XP. Kern
- Xpkern@csri.toronto.edu
- Xpkern@csri.utoronto.ca
- Xpkern@utcsri.uucp (..!utzoo!utcsri!pkern, ..!uunet!utai!pkern)
- END_OF_Readme
- if test 2176 -ne `wc -c <Readme`; then
- echo shar: \"Readme\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f Makefile -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"Makefile\"
- else
- echo shar: Extracting \"Makefile\" \(213 characters\)
- sed "s/^X//" >Makefile <<'END_OF_Makefile'
- X#
- X# Makefile for ru
- X#
- X
- X# CFLAGS= -Ddebug -g
- XCFLAGS= -O -s
- X
- X# CAPLIB= -ltermlib
- XCAPLIB= -ltermcap
- X
- Xru: ru.c
- X $(CC) $(CFLAGS) -o $@ ru.c $(CAPLIB)
- X
- Xman: ru.l
- X nroff -man ru.l > ru.man
- X
- Xclean:
- X -rm -f *.o a.out core
- END_OF_Makefile
- if test 213 -ne `wc -c <Makefile`; then
- echo shar: \"Makefile\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f ru.l -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"ru.l\"
- else
- echo shar: Extracting \"ru.l\" \(2304 characters\)
- sed "s/^X//" >ru.l <<'END_OF_ru.l'
- X.TH RU L Feb/89 local
- X.UC
- X.SH NAME
- Xru \- compact lists of users on all "visible" systems
- X.SH SYNOPSIS
- X.B "ru [-acdmrsuw] [-D domain] [-h host ... | -l user ...]"
- X.SH DESCRIPTION
- X.I Ru
- Xlists the login names of the users currently on all visible systems.
- X.SH Options
- X.IP -a
- Xlist all users, regardless of their login idle time (\fIrwho(1)\fP-inspired).
- X.IP -c
- Xshow a count for multiply-logged users.
- X.\"When combined with -s, include a count of hosts in each domain.
- X.IP -d
- Xlist hosts alphabetically, regardless of their sub-domains
- X.\"group hosts within their sub-domains
- X(forces -s option).
- X.IP -m
- Xshow multiple logins (overrides -c option).
- X.\"squeeze (ignore) multiple logins.
- X.IP -r
- Xproduce \fIrwho(1)\fP-style output (forces -s option).
- X.IP -s
- Xlist users host-by-host instead of domain-by-domain.
- X.\"list users domain-by-domain instead of host-by-host.
- X.IP -u
- Xdisplay uptimes (see \fIruptime(1)\fP) (forces -s option).
- X.IP -w
- Xbreak lines before they wrap around the screen.
- X.\"allow lines to wrap around (ie. single line per heading).
- X.IP "-D domain"
- Xlist only users logged on hosts in the given domain.
- X.IP "-h host ..."
- Xlist only users logged on to the specified host(s).
- X.IP "-l user ..."
- Xlist only hosts with the given user(s) (forces -s option).
- X.PP
- XThe -h and -l options are mutually exclusive since they
- Xboth use the remaining arguments as a search list.
- XEither option should be followed by at least one name.
- X.PP
- XAny system for which data can be found in the
- X.I rwhod(8c)
- Xspooling directory is considered to be a "visible system".
- X.SH FILES
- X/usr/spool/rwho/whod.*
- X.SH SEE ALSO
- Xusers(1), rwho(1C), rwhod(8C), ruptime(1C)
- X.SH HISTORY
- XOriginally created by splicing pieces of
- X.I rwho(1)
- Xsource into
- X.I users(1)
- Xsource.
- XRewritten to try to clean up the hacked code
- Xand to make it easier to add (or delete) options.
- X.PP
- XBug fixes, enhancements and help provided by
- X nispa@hutcs.hut.fi <Tapani Lindgren>,
- X kusalik@damask.uucp,
- X pkh%cs.nott.ac.uk@nss.cs.ucl.ac.uk <Kevin Hopkins>,
- X lamy@ai.toronto.edu <Jean-Francois Lamy>,
- X moraes@ai.toronto.edu <Mark Moraes>
- X.SH BUGS
- XWith the -h option,
- X.I ru
- Xdoesn't care if a host's spool file hasn't
- Xbeen updated within the last 5 minutes.
- X.sp
- XThis might be considered a good example of option overload.
- X.SH CONTACT
- Xpkern@utcsri.uucp or pkern@csri.toronto.edu
- END_OF_ru.l
- if test 2304 -ne `wc -c <ru.l`; then
- echo shar: \"ru.l\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f ru.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"ru.c\"
- else
- echo shar: Extracting \"ru.c\" \(13584 characters\)
- sed "s/^X//" >ru.c <<'END_OF_ru.c'
- X/*
- X * ru - remote users(1)
- X * usage: ru [-acdmrsuw] [-D domain] [-h host ... | -l user ...]
- X * List users on all "visible" hosts.
- X *
- X * Copyright (c) 1989 University of Toronto. All rights reserved.
- X * Anyone may use or copy this software, except that it may not be
- X * sold for profit, that this copyright notice remain intact, and that
- X * credit is given where it is due. The University of Toronto and the
- X * author make no warranty and accept no liability for this software.
- X *
- X * Written by P. Kern (pkern@utcsri)
- X * with bug fixes and suggestions from
- X * nispa@hutcs.hut.fi <Tapani Lindgren>
- X * kusalik@damask.uucp
- X * pkh%cs.nott.ac.uk@nss.cs.ucl.ac.uk <Kevin Hopkins>
- X * lamy@ai.toronto.edu <Jean-Francois Lamy>
- X * moraes@csri.toronto.edu <Mark Moraes>
- X *
- X * $Header: ru.c,v 2.9 89/02/26 13:48:36 pkern Exp $
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/dir.h>
- X#include <sys/file.h>
- X#include <netdb.h>
- X
- X#define MINSTR 8 /* minimum string length */
- X#define HNSZ 32 /* hostname length */
- X#define RWFSZ HNSZ+5 /* spool-file name length */
- X#define MRGN 10 /* margin "tab" size */
- X#define HOUR 3600 /* seconds in an hour */
- X#define RWPERIOD 300 /* std. 5 minute rwho refresh period */
- X#define MAXPORTS 160 /* max tty ports per host */
- X
- Xstruct rw_utmp { /* rwho file user info */
- X char tty[MINSTR]; /* user's tty */
- X char name[MINSTR]; /* user's login */
- X long time; /* login time */
- X long idle; /* idle time */
- X} rut;
- X
- Xstruct rw_hdr { /* rwho data/host info */
- X char pad[4]; /* ignore first 4 bytes */
- X int sent, rcvd; /* time sent, time rec'vd */
- X char host[HNSZ]; /* host's name */
- X int loadav[3]; /* load averages */
- X int boot; /* boot date */
- X} hdr;
- X
- Xint rutsize, hdrsize;
- X#ifdef debug
- X#define RWHODIR "rwho"
- X#else
- X#define RWHODIR "/usr/spool/rwho"
- X#endif
- X
- Xlong now; /* it won't be ... (long now :-) */
- Xint n, fd;
- Xstruct stat st;
- Xchar *hnbuf, *hp; /* hostname buffer & extra pointer */
- Xchar *rubuf, *ep; /* utmp data buffer & end pointer */
- Xchar *program, *domain;
- X /* Flags: if (flag) then ... */
- Xint aflag=1; /* ... only show users with <1 HR idle time */
- Xint sflag=1; /* ... show output by domains (not by hosts) */
- Xint mflag=1; /* ... drop multiple logins */
- Xint cflag=0; /* ... (if mflag) show login counts */
- Xint dflag=1; /* ... sort hostnames within domains */
- Xint Dflag=0; /* ... show users in a given domain */
- Xint hflag=0; /* ... show users on a given host */
- Xint lflag=0; /* ... show hosts with given user */
- Xint rflag=0; /* ... retro -- imitiate rwho */
- Xint uflag=0; /* ... show uptimes (like ruptime) */
- Xint wflag=0; /* ... break lines before wraparound */
- Xint errflag=0;
- X
- Xint wlim=80; /* default screen width */
- X
- Xextern char *rindex(), *malloc(), *getenv();
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X DIR *dirp;
- X struct direct *dp;
- X int rwfcmp(), rutcmp(), drwcmp(); /* qsort() routines */
- X extern int optind; /* see getopt(3C) */
- X extern char *optarg; /* see getopt(3C) */
- X
- X program = argv[0];
- X now = time(0);
- X rutsize = sizeof(rut);
- X hdrsize = sizeof(hdr);
- X
- X while ((n = getopt(argc, argv, "acdhlmrsuwD:")) != EOF)
- X switch(n) {
- X case 'a': aflag=0; break; /* same as rwho(1) */
- X case 'c': cflag=1; break; /* show login count */
- X case 'd': dflag=0; break; /* domain-wise sort */
- X case 'm': mflag=0; break; /* show multi-logins */
- X case 'r': rflag++; break; /* rwho-style output */
- X case 's': sflag=0; break; /* domain-only lists */
- X case 'u': uflag++; break; /* show uptimes */
- X case 'w': wflag++; break; /* break long lines */
- X case 'D': Dflag++; domain = optarg; break;
- X case 'h': hflag++; break; /* host-list follows */
- X case 'l': lflag++; break; /* user-list follows */
- X default: errflag++;
- X }
- X
- X /*
- X * Note: -h and -l are mutually exclusive since both options
- X * use the remaining arguments as a search list. Either option
- X * should be followed by at least one name. The getopt switch
- X * could have been arranged to only use whichever flag (l or h)
- X * was typed last but this way the user will know that there is
- X * a potential problem.
- X */
- X if (errflag || (lflag && hflag)
- X || (optind >= argc && (lflag || hflag))) {
- X fprintf(stderr, "Usage: %s [-acdmrsuw] [-D domain] [-h host ... | -l user ... ]\n", program);
- X exit(1);
- X }
- X
- X if (!dflag || lflag || rflag || uflag) sflag=0;
- X if (!mflag) cflag=0; /* not really needed (see burp()) */
- X
- X if (chdir(RWHODIR) < 0) { /* cd RWHODIR */
- X perror(RWHODIR);
- X exit(1);
- X }
- X
- X if (wflag) { /* wrapping, eh? ok, get screen width */
- X int n;
- X char buf[1024];
- X
- X if ((hp = getenv("TERM")) == NULL) {
- X wflag = 0;
- X#ifdef SQUAWK
- X fprintf(stderr, "%s: no TERM?\n", program);
- X#endif
- X }
- X if (wflag && tgetent(buf, hp) < 0) {
- X wflag = 0;
- X#ifdef SQUAWK
- X fprintf(stderr, "%s: no TERMCAP?\n", program);
- X#endif
- X }
- X if (wflag && (n = tgetnum("co")) > 0 && n > MRGN+MINSTR)
- X wlim = n;
- X }
- X
- X if (hflag) {
- X sflag=0;
- X for ( ;optind < argc; optind++)
- X dohost(argv[optind]);
- X exit(0);
- X }
- X
- X /*
- X * read "." directory (assuming chdir() worked),
- X * and get all files with the "whod." prefix.
- X * if Dflag, only get files ending with "domain".
- X */
- X if ((dirp = opendir(".")) == NULL
- X || stat(".", &st) < 0) {
- X perror(RWHODIR);
- X exit(1);
- X }
- X dp = readdir(dirp); /* get "." */
- X n = (st.st_size/(DIRSIZ(dp)+8))*RWFSZ;
- X hnbuf = malloc((unsigned)n);
- X n = 0; ep = hnbuf;
- X while (dp = readdir(dirp)) {
- X strncpy(ep, dp->d_name, dp->d_namlen);
- X *(ep+dp->d_namlen) = '\0';
- X if (strncmp(ep, "whod.", 5) == 0 &&
- X (!Dflag || strcmp(rindex(ep,'.')+1,domain) == 0)) {
- X ep += RWFSZ;
- X n++;
- X }
- X }
- X /* ep should now point to the end of the host name buffer */
- X closedir(dirp);
- X
- X if (dflag) /* sort host names within domains */
- X qsort(hnbuf, n, RWFSZ, drwcmp);
- X else /* sort full host name */
- X qsort(hnbuf, n, RWFSZ, rwfcmp);
- X
- X if (sflag) { /* process by domains only */
- X dodomains();
- X exit(0);
- X }
- X
- X /*
- X * process each "whod." file in hnbuf list.
- X * - get <filesize> bytes of mem
- X * - gobble rutmp data from file
- X * - sort names alphabetically
- X * - print names (burp)
- X * - free up mem
- X */
- X hp = hnbuf;
- X while (hp < ep) {
- X if ((fd = open(hp, O_RDONLY)) < 0
- X || fstat(fd, &st) < 0) {
- X perror(hp);
- X exit(1);
- X }
- X if ((n = st.st_size-hdrsize) || uflag) {
- X if ((rubuf = malloc((unsigned)n)) == 0) {
- X perror(program);
- X exit(1);
- X }
- X n = read(fd, (char *)&hdr, hdrsize);
- X n = ldrut(fd,rubuf,st.st_size-hdrsize);
- X if (uflag)
- X slurp(&hdr, n/rutsize);
- X else
- X#ifdef debug
- X if (n > 0){
- X#else
- X if (now-hdr.rcvd <= RWPERIOD && n > 0){
- X#endif
- X qsort(rubuf, n/rutsize, rutsize, rutcmp);
- X if (!lflag || chew(rubuf,n,argc,argv))
- X burp(hp, rubuf, n);
- X }
- X }
- X free(rubuf);
- X close(fd);
- X hp += RWFSZ;
- X }
- X}
- X
- X/*
- X * compare rwho spool-file names
- X */
- Xrwfcmp(p, q)
- Xregister char *p, *q;
- X{
- X return(strncmp(p, q, RWFSZ));
- X}
- X
- X/*
- X * compare utmp name entries
- X */
- Xrutcmp(p, q)
- Xregister struct rw_utmp *p, *q;
- X{
- X return(strncmp(p->name, q->name, MINSTR));
- X}
- X
- X/*
- X * compare sub-domain names
- X */
- Xdrwcmp(p, q)
- Xregister char *p, *q;
- X{
- X int x;
- X char *s, *t;
- X
- X s = rindex(p, '.');
- X t = rindex(q, '.');
- X if (s) s++; else s = p;
- X if (t) t++; else t = q;
- X if(x = strncmp(s, t, RWFSZ))
- X return(x);
- X return(strncmp(p, q, RWFSZ));
- X}
- X
- X/*
- X * print "host: user1 user2 ... "
- X * or whatever format the flags dictate.
- X * (blame creeping featurism for this mass of spaghetti)
- X */
- Xburp(s, r, n)
- Xregister char *s, *r;
- Xint n;
- X{
- X int wdent;
- X register int l, wo, sl;
- X register char *xp;
- X char tbuf[RWFSZ+MINSTR+2];
- X
- X if (!sflag) s += 5; /* skip "whod." prefix */
- X
- X if (rflag) { /* rwho-like output */
- X register struct rw_utmp *rp;
- X
- X sprintf(tbuf, "%.*s:", HNSZ, s);
- X sl = strlen(tbuf);
- X for (xp = r; xp < (r+n); xp += rutsize) {
- X rp = (struct rw_utmp *)xp;
- X strncpy(tbuf + sl, rp->tty, MINSTR);
- X printf("%-8.8s %-23s %.12s",
- X rp->name, tbuf, ctime(&rp->time) + 4);
- X if (rp->idle < 60)
- X printf("\n");
- X else {
- X l = rp->idle/HOUR;
- X wo = (rp->idle % HOUR)/60;
- X if (l > 99)
- X wo = 59, l = 99;
- X printf((l) ? " %2d" : " ", l);
- X printf(":%02d\n", wo);
- X }
- X }
- X return;
- X }
- X
- X /* print host- or domain-name */
- X if (sflag && cflag) /* include # of hosts in domain */
- X sprintf(tbuf, "%.*s/%d:", MRGN, s, sflag);
- X else
- X sprintf(tbuf, "%.*s:", MRGN+((!sflag) * 4), s);
- X
- X printf("%-*s", wo = wdent = MRGN+((!sflag) * 5), s = tbuf);
- X
- X if (n && mflag) { /* print "user1 user2 ..." */
- X for(l=0, xp=s=r+MINSTR; s < (r+n); s += rutsize)
- X if (strncmp(s, xp, MINSTR)) {
- X sprintf(tbuf,
- X (l>1)?" %.*s/%d":" %.*s",
- X MINSTR, xp, l);
- X if (wflag) { /* wrap and indent */
- X if ((sl=strlen(tbuf)) > wlim-wo)
- X printf("\n%*s",
- X wo = wdent, "");
- X wo += sl;
- X }
- X fputs(tbuf, stdout);
- X xp = s; l = cflag;
- X }
- X else
- X l += cflag;
- X /* still one name left to do */
- X sprintf(tbuf,(l>1)?" %.*s/%d\n":" %.*s\n",MINSTR,xp,l);
- X if (wflag && (strlen(tbuf)-1) > wlim - wo)
- X printf("\n%*s", wo = wdent, "");
- X fputs(tbuf, stdout);
- X return;
- X }
- X
- X /* ... else don't ignore multi-logins */
- X for (s = r+MINSTR; s < (r+n); s += rutsize) {
- X if (wflag) { /* wrap and indent */
- X if ((sl = strlen(s)) > MINSTR)
- X sl = MINSTR;
- X if (++sl > wlim - wo)
- X printf("\n%*s", wo = wdent, "");
- X wo += sl;
- X }
- X printf(" %.*s", MINSTR, s);
- X }
- X printf("\n");
- X}
- X
- X/*
- X * print uptimes (like ruptime(1))
- X */
- Xslurp(h, n)
- Xstruct rw_hdr *h;
- Xint n;
- X{
- X char tbuf[128];
- X register char *p;
- X register int tdif;
- X
- X /* host name */
- X p = tbuf;
- X sprintf(p, "%-15.15s", h->host);
- X
- X /* if rcvd-time is >1 hour old then assume host is down */
- X tdif = now - h->rcvd; p += 15;
- X if (tdif > HOUR) {
- X if (tdif > (24 * HOUR))
- X sprintf(p, "down %3d+%02d:%02d\n",
- X (tdif / (24 * HOUR)),
- X (tdif % (24 * HOUR)) / HOUR,
- X (tdif % HOUR) / 60);
- X else
- X sprintf(p, "down %6d:%02d\n",
- X tdif / HOUR, (tdif % HOUR) / 60);
- X fputs(tbuf, stdout);
- X return;
- X }
- X
- X /* print host's uptime but include a '*' if
- X * rcvd-time is between 5 mins and 1 hour old */
- X sprintf(p, "%c up ", (tdif > RWPERIOD) ? '*' : ' ');
- X tdif = now - h->boot; p += 5;
- X if (tdif < 1) /* host's boottime > our current time */
- X sprintf(p, " ??:??");
- X else if (tdif > (24 * HOUR))
- X sprintf(p, "%3d+%02d:%02d",
- X (tdif / (24 * HOUR)),
- X (tdif % (24 * HOUR)) / HOUR,
- X (tdif % HOUR) / 60);
- X else
- X sprintf(p, "%6d:%02d", tdif / HOUR, (tdif % HOUR) / 60);
- X
- X /* print # of users and the 3 load numbers */
- X p += 9;
- X sprintf(p, ", %5d user%s load: %2d.%02d, %2d.%02d, %2d.%02d\n",
- X n, (n == 1) ? ", " : "s,",
- X h->loadav[0]/100, h->loadav[0]%100,
- X h->loadav[1]/100, h->loadav[1]%100,
- X h->loadav[2]/100, h->loadav[2]%100);
- X fputs(tbuf, stdout);
- X}
- X
- X/*
- X * show users on a specific host
- X */
- Xdohost(host)
- Xchar *host;
- X{
- X struct hostent *h, *gethostbyname();
- X
- X /*
- X * try to get host's proper name
- X * and try to find the proper spool file
- X */
- X if((h = gethostbyname(host)) == NULL) {
- X hp = malloc(strlen(host)+MINSTR);
- X sprintf(hp, "whod.%s", host);
- X/*
- X perror(host);
- X return(1);
- X */
- X }
- X else {
- X hp = malloc(strlen(h->h_name)+MINSTR);
- X sprintf(hp, "whod.%s", h->h_name);
- X }
- X if ((fd = open(hp, O_RDONLY)) < 0 && h != NULL) {
- X char **s;
- X /*
- X * can't find file related to h_name
- X * try the aliases instead.
- X */
- X s = h->h_aliases;
- X while(*s) {
- X free(hp);
- X hp = malloc(strlen(*s)+MINSTR);
- X sprintf(hp, "whod.%s", *s);
- X if ((fd = open(hp, O_RDONLY)) > 0)
- X break;
- X s++;
- X }
- X if (*s == NULL) {
- X fprintf(stderr, "%s: no data\n", host);
- X return(1);
- X }
- X }
- X if ((fd > 0 && fstat(fd, &st) < 0) || stat(hp, &st) < 0) {
- X if (fd < 0)
- X fprintf(stderr, "%s: unknown host\n", host);
- X else
- X perror(hp);
- X return(1);
- X }
- X n = st.st_size - hdrsize;
- X if ((rubuf = malloc((unsigned)n)) == 0) {
- X perror(program);
- X exit(1);
- X }
- X n = read(fd, (char *)&hdr, hdrsize);
- X n = ldrut(fd,rubuf,st.st_size-hdrsize);
- X if (uflag)
- X slurp(&hdr, n/rutsize);
- X else {
- X if (now-hdr.rcvd > RWPERIOD)
- X strcat(hp, "*");
- X qsort(rubuf, n/rutsize, rutsize, rutcmp);
- X burp(hp, rubuf, n);
- X }
- X}
- X
- X/*
- X * show users by domain
- X */
- Xdodomains()
- X{
- X int z;
- X register int i;
- X char *p0, *p1, *fnp, *rbp;
- X
- X fnp = hp = hnbuf;
- X
- X if ((rubuf = malloc(n * MAXPORTS * rutsize)) == NULL) {
- X perror(program);
- X exit(1);
- X }
- X
- X p0 = rindex(fnp, '.') + 1;
- X if ((int)p0 == 1) p0 = fnp;
- X
- X while (fnp < ep) {
- X rbp = rubuf;
- X for (p1=p0, n=i=0; fnp < ep && !strcmp(p1, p0); i++) {
- X if ((fd = open(fnp, O_RDONLY)) < 0
- X || fstat(fd, &st) < 0) {
- X perror(fnp);
- X exit(1);
- X }
- X read(fd, (char *)&hdr, hdrsize);
- X z = ldrut(fd,rbp,st.st_size-hdrsize);
- X#ifdef debug
- X if (z > 0) {
- X#else
- X if (now-hdr.rcvd <= RWPERIOD && z > 0) {
- X#endif
- X n += z;
- X rbp += z;
- X }
- X close(fd);
- X fnp += RWFSZ;
- X p1 = p0;
- X p0 = rindex(fnp, '.') + 1;
- X if ((int)p0 == 1) p0 = fnp;
- X }
- X if (!n) continue;
- X *rbp = '\0';
- X qsort(rubuf, n/rutsize, rutsize, rutcmp);
- X sflag = i;
- X burp(p1, rubuf, n);
- X }
- X free(rubuf);
- X}
- X
- X/*
- X * load rutmp data into buffer.
- X */
- Xldrut(fd, p, n)
- Xint fd, n;
- Xchar *p;
- X{
- X register int m1, m2, nr;
- X register char *s;
- X
- X if (!aflag) return(read(fd, p, n));
- X
- X s = p;
- X m1 = m2 = 0;
- X
- X while (m2 < n && (nr = read(fd, s, rutsize)) > 0) {
- X m2 += nr;
- X if (((struct rw_utmp *)s)->idle > HOUR)
- X /* ignore entries with >1 hr idle time */
- X continue;
- X m1 += nr;
- X s += nr;
- X }
- X return(m1);
- X}
- X
- X/*
- X * search a file's data for given users
- X */
- Xchew(r, n, ac, av)
- Xchar *r, *av[];
- Xint n, ac;
- X{
- X register int i;
- X register char *p;
- X extern int optind;
- X
- X /* grotty old standard linear search */
- X for (p = r+MINSTR; p < (r+n); p += rutsize)
- X for (i=optind; i<ac; i++)
- X if (*p == av[i][0]
- X && !strncmp(av[i], p, MINSTR))
- X return (1);
- X return(0);
- X}
- END_OF_ru.c
- if test 13584 -ne `wc -c <ru.c`; then
- echo shar: \"ru.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of shell archive.
- exit 0
-
-